/* Network Initialization */

#include "lwip/init.h"
#include "lwip/tcpip.h"
#include "lwip/netif.h"
#include "lwip/dhcp.h"
#include "lwip/etharp.h"
#include "lwip/ip_addr.h"
#include "lwip/err.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

/* Network interface structure */
static struct netif g_netif;

/* Network interface initialization callback */
static err_t netif_init_callback(struct netif *netif)
{
    LWIP_ASSERT("netif != NULL", (netif != NULL));
    netif->mtu = 1500;
    netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
    netif->state = NULL;
    netif->name[0] = 'e';
    netif->name[1] = 'n';
    netif->linkoutput = NULL; /* TODO: Implement link output function */
    netif->output = etharp_output;
    
    return ERR_OK;
}

/* Network link status callback */
static void netif_link_callback(struct netif *netif)
{
    if (netif_is_link_up(netif)) {
        printf("Network link is up\n");
        /* Start DHCP client */
        dhcp_start(netif);
    } else {
        printf("Network link is down\n");
        /* Stop DHCP client */
        dhcp_stop(netif);
    }
}

/* Network thread */
static void network_thread(void *arg)
{
    printf("Network thread started\n");
    
    /* TODO: Implement network main loop */
    
    vTaskDelete(NULL);
}

/* Initialize network */
void network_init(void)
{
    ip_addr_t ipaddr, netmask, gw;
    
    printf("Initializing network...\n");
    
    /* Initialize lwIP */
    lwip_init();
    
    /* Start TCP/IP thread */
    tcpip_init(NULL, NULL);
    
    /* Configure IP addresses */
    IP4_ADDR(&gw, 0, 0, 0, 0);
    IP4_ADDR(&ipaddr, 0, 0, 0, 0);
    IP4_ADDR(&netmask, 0, 0, 0, 0);
    
    /* Add network interface */
    netif_add(&g_netif, &ipaddr, &netmask, &gw, NULL, netif_init_callback, tcpip_input);
    
    /* Set default network interface */
    netif_set_default(&g_netif);
    
    /* Set network link callback */
    netif_set_link_callback(&g_netif, netif_link_callback);
    
    /* Bring network interface up */
    netif_set_up(&g_netif);
    
    /* Create network thread */
    xTaskCreate(network_thread, "network_thread", 1024, NULL, 5, NULL);
    
    printf("Network initialization completed\n");
}
